﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Drawing;
using System.Text.RegularExpressions;

namespace Vit.Report.XmlWebReport
{
    public class CellElement
    {
        protected Page page;
        protected double lineHeight;

        public CellElement(Page page, string topLeftPosition, string bottomRightPosition, string content)
        {
            this.page = page;
            this.RectanglePosition = new RectanglePosition(topLeftPosition, bottomRightPosition);
            this.Content = content;
            this.IsHeader = false;
            this.IsFooter = false;
            Initialize();
        }

        public CellElement(Page page, RectanglePosition rect, string content)
        {
            this.page = page;
            this.RectanglePosition = rect;
            this.Content = content;
            this.IsHeader = false;
            this.IsFooter = false;
            Initialize();
        }

        protected virtual void Initialize()
        {
            PositionType = PositionType.Auto;
            IsPrintable = true;
            CssClass = "element middle";
            this.Font = this.page.DefaultFont;
            this.Editable = false;
            this.IsHtml = false;
            this.NoWrap = false;
            this.Format = "{0}";
            AddToPage();
        }

        protected virtual void AddToPage()
        {
            this.page.Elements.Add(this);
            Index = this.page.Elements.Count;
        }

        public virtual void CalculatePosition()
        {
            if (string.IsNullOrEmpty(ID))
                ID = string.Format("{0}_{1}_{2}", page.ID, RectanglePosition.TopLeftPosition, RectanglePosition.BottomRightPosition);

            if (IsPrintable == false)
                return;

            //if (this.IsHtml)
            //{
                this.content = ReportHelper.TrimHtml(this.content);
            //}

            if (this.IsHeader || this.IsFooter)
                return;

            if (PositionType == PositionType.Auto)
            {
                for (int i = 0; i < Index; i++)
                {
                    var positionType = page.Elements[i].PositionType;
                    if (positionType == PositionType.RuntimeCalculationSource || positionType == PositionType.RuntimeCalculation)
                    {
                        PositionType = PositionType.RuntimeCalculation;
                        break;
                    }
                }
            }

            if (PositionType == PositionType.RuntimeCalculation || PositionType == PositionType.RuntimeGeneration)
            {
                RectanglePosition.Move(page.XOffset, page.YOffset);
            }
            else if (PositionType == PositionType.AutoFix && page.YOffset > 0)
            {
                RectanglePosition.Move(0, page.ContentRectanglePosition.YSpan);
            }

            string split = string.Empty;


            int yOffset = 0;
            if(NoWrap == false)
                yOffset = ReportHelper.AppendWithContent(this.Font, page, this.RectanglePosition, this.PositionType, ref this.content, out split);

            RectanglePosition rightRect = null;
            RectanglePosition bottomRect = null;
            this.RectanglePosition.Crop(page.ContentRectanglePosition, out rightRect, out bottomRect);

            if (rightRect != null)
            {
                page.EnsureExtraXPage();
                CreateExtraElement(page.ExtraXPage, rightRect, "");
            }

            if (bottomRect != null)
            {
                if (yOffset <= 0 && string.IsNullOrEmpty(split))
                    split = this.content;
                if (!string.IsNullOrEmpty(SplitTo))
                {
                    page.Javascripts += string.Format("$('#{0}_content').html('{1}');", SplitTo, split);
                }
                else
                {
                    this.page.YOffset += yOffset;
                    page.EnsureExtraYPage();
                    CreateExtraElement(page.ExtraYPage, bottomRect, split);
                }
            }
            else if (yOffset > 0)
            {
                this.page.YOffset += yOffset;
            }
        }

        public virtual void Render(TextWriter writer)
        {
            if (IsPrintable == false)
                return;

            RectanglePosition.Render(writer,
                ID, string.Format(Format, Content), CssClass, CssStyle, 50 + this.Index, this.Font, page);
        }

        public virtual CellElement CreateExtraElement(Page extraPage, RectanglePosition rect, string content)
        {
            CellElement cell = new CellElement(extraPage, rect, content);
            cell.ID = string.Format("{0}_extraEle", this.ID);
            cell.Move(0, cell.Page.HeaderOffset);
            cell.CssClass = this.CssClass;
            cell.CssStyle = this.CssStyle;
            cell.Font = this.Font;
            cell.Format = this.Format;
            cell.LineHeight = this.LineHeight;
            cell.LetterSpacing = this.LetterSpacing;
            cell.NoWrap = this.NoWrap;
            cell.IsHtml = this.IsHtml;
            cell.IsFooter = this.IsFooter;
            cell.IsHeader = this.IsHeader;
            cell.PositionType = PositionType.RuntimeGeneration;
            return cell;
        }

        public virtual void Move(int xOffset, int yOffset)
        {
            this.RectanglePosition.Move(xOffset, yOffset);
        }

        public virtual void Append(float width, float height)
        {
            this.RectanglePosition.Append(width, height);
        }

        public virtual void Offset(float x, float y)
        {
            this.RectanglePosition.Offset(x, y);
        }

        protected string content;
        public string Content { get { return content; } set { content = value; } }
        public int Index { get; internal set; }
        public RectanglePosition RectanglePosition { get; set; }
        public PositionType PositionType { get; set; }
        public bool IsPrintable { get; set; }
        public Page Page { get { return this.page; } }
        public Font Font { get; set; }
        public string CssClass { get; set; }
        public string CssStyle { get; set; }
        public string Format { get; set; }
        public string ID { get; set; }
        public string SplitTo { get; set; }
        public bool IsHtml { get; set; }
        public double LineHeight
        {
            get
            {
                if (RectanglePosition != null)
                    return RectanglePosition.LineHeight;
                return 1.0;
            }
            set
            {
                if (RectanglePosition != null)
                    RectanglePosition.LineHeight = value;
            }
        }
        public double LetterSpacing
        {
            get
            {
                if (RectanglePosition != null)
                    return RectanglePosition.LetterSpacing;
                return 1.0;
            }
            set
            {
                if (RectanglePosition != null)
                    RectanglePosition.LetterSpacing = value;
            }
        }
        public bool Editable
        {
            get
            {
                if (RectanglePosition != null)
                    return RectanglePosition.Editable;
                return false;
            }
            set
            {
                if (RectanglePosition != null)
                    RectanglePosition.Editable = value;
            }
        }
        public bool NoWrap { get; set; }
        public bool IsHeader { get; set; }
        public bool IsFooter { get; set; }
    }
}
